from django.shortcuts import render
from django.views import View
import json
from django import http
from goods.models import SKU
from django_redis import get_redis_connection
import pickle
import base64

# 1,添加购物车视图
class CartView(View):
    def post(self,request):
        # 1,获取参数
        dict_data = json.loads(request.body.decode())
        sku_id = dict_data.get("sku_id")
        count = int(dict_data.get("count"))
        selected = dict_data.get("selected",True)

        # 2,为空校验（校验sku_id对应的商品是否存在，count数量是否合法）
        if not all([sku_id,count]):
            return http.JsonResponse({"code":4000,"errmsg":"参数不全"})

        # 3,库存是否足够
        stock = SKU.objects.get(id=sku_id).stock
        if count > stock:
            return http.JsonResponse({"code":4001,"errmsg":"库存不够"})

        # 4,判断用户登录状态
        if request.user.is_authenticated:
            #4,1获取redis对象
            redis_conn = get_redis_connection("carts")
            #4,2存储购物车数据
            redis_conn.hincrby(f"carts_{request.user.id}",sku_id,count)
            #4,3,设置商品的选中状态
            if selected:
                redis_conn.sadd(f"selected_{request.user.id}",sku_id)
            response = http.JsonResponse({"code": 0, "errmsg": "添加购物车成功"})
        else:
            # 4,4获取cookie中的数据
            cart_cookie = request.COOKIES.get("carts")
            # 4,5创建字符串转成字典
            cart_cookie_dict = {}
            if cart_cookie:
                cart_cookie_dict = pickle.loads(base64.b64decode(cart_cookie.encode()))

            # 4,6 累加count数量
            if sku_id in cart_cookie_dict:
                old_count = cart_cookie_dict[sku_id]["count"]
                count += old_count

            # 4,7 更新购物车字典数据
            cart_cookie_dict[sku_id] = {
                "count":count,
                "selected":selected
            }

            # 4,8设置cookie数据
            response = http.JsonResponse({"code":0,"errmsg":"添加购物车成功"})
            cart_cookie_str = base64.b64encode(pickle.dumps(cart_cookie_dict)).decode()
            response.set_cookie("carts",cart_cookie_str)

        # 5,返回响应
        return response

    def get(self,request):
        # 1,判断用户是否登录
        if request.user.is_authenticated:
            # 1,1获取redis的购物车数据
            redis_conn = get_redis_connection("carts")
            cart_dict = redis_conn.hgetall(f"carts_{request.user.id}")
            select_list = redis_conn.smembers(f"selected_{request.user.id}")

            # 1,2数据拼接转换
            sku_list = []
            for sku_id in cart_dict.keys():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    "id":sku.id,
                    "default_image_url":sku.default_image_url.url,
                    "name":sku.name,
                    "price":str(sku.price),
                    "count":int(cart_dict[sku_id]),
                    "amount":str(int(cart_dict[sku_id])*sku.price),
                    "selected":str(sku_id in select_list)
                }
                sku_list.append(sku_dict)
        else:
            # 1,3获取cookie中的购物车数据
            cart_cookie = request.COOKIES.get("carts")

            # 1,4将字符串数据转成字典数据
            cart_cookie_dict = {}
            if cart_cookie:
                cart_cookie_dict = pickle.loads(base64.b64decode(cart_cookie.encode()))

            # 1,5数据转换
            sku_list = []
            for sku_id,selected_count in cart_cookie_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    "id": sku.id,
                    "default_image_url": sku.default_image_url.url,
                    "name": sku.name,
                    "price": str(sku.price),
                    "count": int(selected_count["count"]),
                    "amount": str(int(selected_count["count"]) * sku.price),
                    "selected": str(selected_count["selected"])
                }
                sku_list.append(sku_dict)

        # 2,返回响应
        return render(request,template_name='cart.html',context={"sku_list":sku_list})

    def put(self,request):
        # 1，获取参数
        dict_data = json.loads(request.body.decode())
        sku_id = dict_data.get("sku_id")
        count = int(dict_data.get("count",0))
        selected = str(dict_data.get("selected",'True'))

        # 2，参数校验（sku对应的商品是否存在，count数量是否合理）
        if not all([sku_id,count,selected]):
            return http.JsonResponse({"code":4000,"errmsg":"参数不全"})

        # 补充，需要等selected判断完成之后再转换
        selected = True if selected == 'True' else False

        # 3，判断库存是否足够
        sku = SKU.objects.get(id=sku_id)
        if count > sku.stock:
            return http.JsonResponse({"code":4001,"errmsg":"库存不足"})

        # 4，修改数据
        if request.user.is_authenticated:
            # 4,1获取redis链接对象
            redis_conn = get_redis_connection("carts")
            # 4,2修改数据
            redis_conn.hset(f"carts_{request.user.id}",sku_id,count)
            # 4,3选中状态
            if selected:
                redis_conn.sadd(f"selected_{request.user.id}",sku_id)
            else:
                redis_conn.srem(f"selected_{request.user.id}",sku_id)
            # 4,4拼接数据
            sku_dict = {
                "id": sku.id,
                "default_image_url": sku.default_image_url.url,
                "name": sku.name,
                "price": str(sku.price),
                "count": int(count),
                "amount": str(int(count) * sku.price),
                "selected": selected
            }
            # 创建响应对象
            response = http.JsonResponse({"code": 0, "errmsg": "获取成功", "cart_sku": sku_dict})
        else:
            # 4,5获取cookie中的数据
            cart_cookie = request.COOKIES.get("carts")
            # 4,6字符串转字典
            cart_cookie_dict = {}
            if cart_cookie:
                cart_cookie_dict = pickle.loads(base64.b64decode(cart_cookie.encode()))
            # 4,7修改数据
            cart_cookie_dict[sku_id] = {
                "selected":selected,
                "count":count
            }
            # 4,8拼接字典数据
            sku_dict = {
                "id": sku.id,
                "default_image_url": sku.default_image_url.url,
                "name": sku.name,
                "price": str(sku.price),
                "count": int(count),
                "amount": str(int(count) * sku.price),
                "selected": selected
            }
            response = http.JsonResponse({"code": 0, "errmsg": "获取成功", "cart_sku": sku_dict})
            cookie_cart_str = base64.b64encode(pickle.dumps(cart_cookie_dict)).decode()
            response.set_cookie("carts", cookie_cart_str)

        # 5，返回响应
        return response

    def delete(self,request):
        # 1，获取参数
        dict_data = json.loads(request.body.decode())
        sku_id = dict_data.get("sku_id")

        # 2，校验参数
        if not sku_id:
            return http.JsonResponse({"code":4000,"errmsg":"参数不全"})

        # 3，数据处理
        if request.user.is_authenticated:
            # 3，1删除数据
            redis_conn = get_redis_connection("carts")
            redis_conn.hdel(f"carts_{request.user.id}",sku_id)
            redis_conn.srem(f"selected_{request.user.id}",sku_id)
            # 创建响应对象
            response = http.JsonResponse({"code":0,"errmsg":"删除成功"})
        else:
            # 3,2 获取cookie数据
            cookie_cart = request.COOKIES.get("carts")
            # 3,3 字典数据转换
            cookie_cart_dict = {}
            if cookie_cart:
                cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))
            # 3,4删除数据
            if sku_id in cookie_cart_dict:
                del cookie_cart_dict[sku_id]
            # 3,4数据拼接
            response = http.JsonResponse({"code": 0, "errmsg": "删除成功"})
            cookie_cart_str = base64.b64encode(pickle.dumps(cookie_cart_dict)).decode()
            response.set_cookie("carts",cookie_cart_str)

        # 4，返回响应
        return response

# 2,全选购物车
class CartSelectedAllView(View):
    def put(self,request):
        # 1,获取参数
        dict_data = json.loads(request.body.decode())
        selected = dict_data.get("selected")

        # 2,校验参数
        try:
            selected = bool(selected)
        except Exception as e:
            return http.JsonResponse({"code":4001,"errmsg":"参数类型有误"})

        # 3,数据入库
        if request.user.is_authenticated:
            #3,1获取redis对象
            redis_conn = get_redis_connection("carts")
            cart_dict = redis_conn.hgetall(f"carts_{request.user.id}")
            sku_ids = cart_dict.keys()

            #3,2修改选中状态
            if selected:
                redis_conn.sadd(f"selected_{request.user.id}",*sku_ids)
            else:
                redis_conn.srem(f"selected_{request.user.id}",*sku_ids)

            # 创建响应体对象
            response = http.JsonResponse({"code": 0, "errmsg": "修改成功"})
        else:
            #3,3获取cookie中购物车数据
            cookie_cart = request.COOKIES.get("carts")

            #3,4字符串数据转字典数据
            cookie_cart_dict = {}
            if cookie_cart:
                cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            #3,5修改cookie数据
            for sku_id,selected_count in cookie_cart_dict.items():
                selected_count["selected"] = selected

            # 3,6创建响应体对象
            response = http.JsonResponse({"code": 0, "errmsg": "修改成功"})
            cookie_cart_str = base64.b64encode(pickle.dumps(cookie_cart_dict)).decode()
            response.set_cookie("carts",cookie_cart_str)

        # 4,返回响应
        return response

# 3,简要购物车
class CartSimpleView(View):
    def get(self,request):
        #1,判断用户登录状态，返回数据
        if request.user.is_authenticated:
            #1,1 获取redis数据
            redis_conn = get_redis_connection("carts")
            cart_dict = redis_conn.hgetall(f"carts_{request.user.id}")
            selected_list = redis_conn.smembers(f"selected_{request.user.id}")

            #1,2 数据拼接
            sku_list = []
            for sku_id in cart_dict.keys():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    "id":sku.id,
                    "default_image_url":sku.default_image_url.url,
                    "name":sku.name,
                    "count":int(cart_dict[sku_id])
                }
                sku_list.append(sku_dict)
        else:
            #1,3获取cookie数据
            cookie_cart = request.COOKIES.get("carts")

            #1，4字符串转字典
            cookie_cart_dict = {}
            if cookie_cart:
                cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            #1，5数据转换
            sku_list = []
            for sku_id,selected_count in cookie_cart_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    "id": sku.id,
                    "default_image_url": sku.default_image_url.url,
                    "name": sku.name,
                    "count": int(selected_count["count"])
                }
                sku_list.append(sku_dict)


        # 2,返回响应
        return http.JsonResponse({"code":0,"cart_skus":sku_list})